
#include "StdAfx.h"
#include "MonitorClient.h"
#include "LvLayoutManager.h"
#include "DBManager.h"
#include "ApplicationData.h"
#include "MultiDisplayDlg.h"
#include "MonitorMessage.h"
#include "MonitorPlatform.h"

CLvLayoutManager::CLvLayoutManager(void)
: m_pMultiDisplayDlg(NULL)
, m_ActiveLayoutIter(EndOfLayoutList())
, m_bTouring(FALSE)
, m_bEnableSelChange(FALSE)
{
	m_TourTimer.SetTimerProc(LayoutTourTimerProc, this);
}

CLvLayoutManager::~CLvLayoutManager(void)
{
	CLiveViewLayoutPtrList::iterator it = m_Layoutlist.begin();
	for(; it != m_Layoutlist.end(); ++it)
	{
		delete *it;
	}
}

BOOL CLvLayoutManager::Initialize(CMultiDisplayDlg* pMultiDisplayDlg)
{
	CLiveViewLayoutInfoArray LayoutInfoArray;

	if(!theDBManager->LoadLiveViewLayoutList(LayoutInfoArray, theUser->GetUserID()))
	{
		return FALSE;
	}

	m_pMultiDisplayDlg = pMultiDisplayDlg;

	CLiveViewLayoutInfoArray::iterator it = LayoutInfoArray.begin();
	for(; it != LayoutInfoArray.end(); ++it)
	{
		CLiveViewLayout* pLayout = new CLiveViewLayout(static_cast<int>(m_Layoutlist.size()), pMultiDisplayDlg, *it);
		m_Layoutlist.push_back(pLayout);		
	}

	if(m_Layoutlist.empty())
	{
		LIVEVIEW_LAYOUT_PROPERTY Prop;
		Prop.strLayoutName = LOAD_STRING(_T("ID_string_default_layout"));
		Prop.nDisplayNum = theAppData.GetPreviewWindowNumber();
		Prop.nStayTime = LAYOUT_TOUR_STAY_TIME_DEFAULT;

		LAYOUT_ITER Iter = AddLayout(Prop);

		if(Iter == EndOfLayoutList())
			return FALSE;
	}

	//SetActiveLayout(m_Layoutlist.begin());

	LAYOUT_ITER Iter = m_Layoutlist.begin();
	CLiveViewLayout* pLayout = *Iter;

	DWORD dwDisplayStyle = m_pMultiDisplayDlg->GetDisplayStyle();
	m_pMultiDisplayDlg->SetDisplayNum(pLayout->GetDisplayNumber(), FALSE);
	m_ActiveLayoutIter = Iter;

	return TRUE;
}

LAYOUT_ITER CLvLayoutManager::AddLayout(LIVEVIEW_LAYOUT_PROPERTY& LayoutProp)
{
	if(!theDBManager->AddLiveViewLayout(LayoutProp, theUser->GetUserID()))
	{
		return m_Layoutlist.end();
	}

	LIVEVIEW_LAYOUT_INFO LayoutInfo(LayoutProp);
	CLiveViewLayout* pLayout = new CLiveViewLayout(static_cast<int>(m_Layoutlist.size()), m_pMultiDisplayDlg, LayoutInfo);

	m_Layoutlist.push_back(pLayout);

	LAYOUT_ITER Iter = (--(m_Layoutlist.end()));

	return Iter;
}

LAYOUT_ITER CLvLayoutManager::AddLayout(LPCTSTR lpszLayoutName)
{
	LIVEVIEW_LAYOUT_PROPERTY Prop;

	Prop.strLayoutName = lpszLayoutName;
	Prop.nDisplayNum = theAppData.GetPreviewWindowNumber();
	Prop.nStayTime = LAYOUT_TOUR_STAY_TIME_DEFAULT;

	return AddLayout(Prop);
}

BOOL CLvLayoutManager::DeleteLayout(int nIndex)
{
	LAYOUT_ITER Iter = GetLayoutIterator(nIndex);
	ASSERT(Iter != EndOfLayoutList());

	CLiveViewLayout* pLayout = *Iter;

	if(!theDBManager->DeleteLiveViewLayout(pLayout->GetLayoutID()))
	{
		return FALSE;
	}

	if(Iter == m_ActiveLayoutIter)
		m_ActiveLayoutIter = EndOfLayoutList();

	m_Layoutlist.erase(Iter++);
	delete pLayout;

	UpdateLayoutIndex(Iter, nIndex);

	return TRUE;
}

void CLvLayoutManager::SetActiveLayout(LAYOUT_ITER Iter)
{
	if(Iter == m_ActiveLayoutIter || Iter == EndOfLayoutList())
		return;

	if(m_ActiveLayoutIter != EndOfLayoutList())
	{
		(*m_ActiveLayoutIter)->TakeSnapshot();
	}

	int nCloseWnd[100] = {0};
	int nMaxWnd = m_pMultiDisplayDlg->GetMaxDisplayNum();

	for(int i = 0; i < nMaxWnd; i++)
	{
		CMediaPlayer* pMediaPlayer = m_pMultiDisplayDlg->GetMediaPlayer(i);
		if(pMediaPlayer /*&& pMediaPlayer->IsPlaying()*/)
		{
			nCloseWnd[i] = 1;
			if (pMediaPlayer->IsLocalRecording())
			{
				m_pMultiDisplayDlg->RecordStop(i);
			}
		}
	}

	CLiveViewLayout* pLayout = *Iter;

	const CWndChannelIDMap& WndChannelIDMap = pLayout->GetWndChannelIDMap();
	CWndChannelIDMap::const_iterator it = WndChannelIDMap.begin();

	DWORD dwDisplayStyle = m_pMultiDisplayDlg->GetDisplayStyle();
	if(dwDisplayStyle != DISPLAY_NORMAL && dwDisplayStyle != DISPLAY_MULTI_WND_FULL_SCREEN)
		m_pMultiDisplayDlg->RestoreNormalDisplayStyle();

	m_pMultiDisplayDlg->SetDisplayNum(pLayout->GetDisplayNumber(), FALSE);

	for(int i = 0; i < nMaxWnd; i++)
	{
		if(nCloseWnd[i])
		{
			m_pMultiDisplayDlg->LayoutClear(i);
			//CMediaPlayer* pMediaPlayer = m_pMultiDisplayDlg->GetMediaPlayer(i);
			//pMediaPlayer->Clear();
		}
	}
	for(; it != WndChannelIDMap.end(); ++it)
	{
		CChannel* pChannel = thePlatform.FindChannel(it->second);
		if(pChannel)
		{
			m_pMultiDisplayDlg->OpenLive(it->first, pChannel, theAppData.GetLiveStreamType());
			nCloseWnd[it->first] = 0;
		}
	}


	m_ActiveLayoutIter = Iter;

	CLiveViewLayoutMessage Message(ACTIVE_LAYOUT_CHANGED);

	Message.nLayoutIndex = pLayout->GetIndex();
	Message.Send();
}

CLiveViewLayout* CLvLayoutManager::GetNextLayout(LAYOUT_ITER& Iter)
{
	CLiveViewLayout* pLayout = NULL;

	if(Iter != m_Layoutlist.end())
	{
		pLayout = *Iter;
		++Iter;
	}

	return pLayout;
}

LAYOUT_ITER CLvLayoutManager::GetLayoutIterator(int nIndex)
{
	if(nIndex < 0)
		return m_Layoutlist.end();

	LAYOUT_ITER Iter = m_Layoutlist.begin();
	for(int i = 0; i < nIndex && Iter != m_Layoutlist.end(); i++)
	{
		++Iter;		
	}

	return Iter;
}

void CLvLayoutManager::SetActiveLayout(int nIndex)
{
	LAYOUT_ITER Iter = GetLayoutIterator(nIndex);

	SetActiveLayout(Iter);
}

void CLvLayoutManager::UpdateLayoutIndex(LAYOUT_ITER FirstIter, int nFirstIndex)
{
	LAYOUT_ITER Iter = FirstIter;
	int nIndex = nFirstIndex;

	for(; Iter != EndOfLayoutList(); ++Iter)
	{
		CLiveViewLayout* pLayout = *Iter;
		pLayout->SetIndex(nIndex);
		nIndex++;
	}
}

BOOL CLvLayoutManager::SaveAllLayouts()
{
	if(m_ActiveLayoutIter != m_Layoutlist.end())
	{
		(*m_ActiveLayoutIter)->TakeSnapshot();
	}

	LAYOUT_ITER Iter = m_Layoutlist.begin();
	for(; Iter != m_Layoutlist.end(); ++Iter)
	{
		if(!(*Iter)->SaveLayoutInfo())
			break;
	}

	return (Iter == m_Layoutlist.end());
}

BOOL CLvLayoutManager::StartTourLayout()
{
	if(m_bTouring)
		return TRUE;

	if(!m_TourTimer.StartTimer(theAppData.GetLayoutTourTime() * 1000))
	{
		//theErrorLog.SetLastError(_T("start timer failed\n"));
		return FALSE;
	}

	DWORD dwDisplayStyle = m_pMultiDisplayDlg->GetDisplayStyle();
	if(dwDisplayStyle != DISPLAY_NORMAL && dwDisplayStyle != DISPLAY_MULTI_WND_FULL_SCREEN)
		m_pMultiDisplayDlg->RestoreNormalDisplayStyle();

	m_bTouring = TRUE;

	CLiveViewLayoutMessage Message(LAYOUT_TOUR_STARTED);
	Message.Send();

	return TRUE;
}

void CLvLayoutManager::StopTourLayout()
{
	if(m_bTouring)
	{
		m_TourTimer.CloseTimer();
		m_bTouring = FALSE;

		CLiveViewLayoutMessage Message(LAYOUT_TOUR_STOPPED);
		Message.Send();
	}
}

void CLvLayoutManager::LayoutTourTimerProc(UINT uTimerID, LPVOID pUserData)
{
	CLvLayoutManager* pThis = static_cast<CLvLayoutManager*>(pUserData);

	pThis->m_TourTimer.CloseTimer();

	LAYOUT_ITER Iter = pThis->m_ActiveLayoutIter;
	++Iter;

	if(Iter == pThis->m_Layoutlist.end())
		Iter = pThis->m_Layoutlist.begin();

	pThis->SetActiveLayout(Iter);

	pThis->m_TourTimer.StartTimer(theAppData.GetLayoutTourTime() * 1000);
}

void CLvLayoutManager::LoadChannelInfos(int nIndex)
{
	m_bEnableSelChange = TRUE;
	LAYOUT_ITER Iter = GetLayoutIterator(nIndex);

	int nCloseWnd[100] = {0};
	int nMaxWnd = m_pMultiDisplayDlg->GetMaxDisplayNum();

	for(int i = 0; i < nMaxWnd; i++)
	{
		CMediaPlayer* pMediaPlayer = m_pMultiDisplayDlg->GetMediaPlayer(i);
		if(pMediaPlayer /*&& pMediaPlayer->IsPlaying()*/)
		{
			nCloseWnd[i] = 1;
		}
	}

	CLiveViewLayout* pLayout = *Iter;

	const CWndChannelIDMap& WndChannelIDMap = pLayout->GetWndChannelIDMap();
	CWndChannelIDMap::const_iterator it = WndChannelIDMap.begin();

	for(; it != WndChannelIDMap.end(); ++it)
	{
		CChannel* pChannel = thePlatform.FindChannel(it->second);
		if(pChannel)
		{
			m_pMultiDisplayDlg->OpenLive(it->first, pChannel, theAppData.GetLiveStreamType());
			nCloseWnd[it->first] = 0;
		}
	}

	for(int i = 0; i < nMaxWnd; i++)
	{
		if(nCloseWnd[i])
		{
			m_pMultiDisplayDlg->LayoutClear(i);
		}
	}

	m_ActiveLayoutIter = Iter;
}
